package com.flatfish.acvsystem.uitl;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SHAUtils {
	
	/**
	 * 缓冲区大小
	 */
	final static int BUFFER_SIZE = 256 * 1024;
	 
	/**
	 * @author  luohuida
	 * @time    Mar 7, 2015
	 * @param filePath
	 * @return
	 * @Description <b>对文件进行hash，以字符串形式返回40位的哈希值</b>
	 */
	public static String SHAFileByLocalPath(String filePath) {
		FileInputStream fileInputStream = null;  
	    DigestInputStream digestInputStream = null;  
	    
	    try {
			MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
			/*使用DigestInputStream  */
	        fileInputStream = new FileInputStream(filePath);  
	        digestInputStream = new DigestInputStream(fileInputStream,messageDigest);
	        
	        /*read的过程中进行SHA处理，直到读完文件  */
	        byte[] buffer =new byte[BUFFER_SIZE];  
	        while (digestInputStream.read(buffer) > 0);  
	        
	        /*转换并返回结果，也是字节数组，包含16个元素  */
	        byte[] resultByteArray = messageDigest.digest();  
	        /*字符数组转换成字符串返回 */
	        return byteArrayToHex(resultByteArray); 
	        
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				digestInputStream.close();
				fileInputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * @author  luohuida
	 * @time    Mar 7, 2015
	 * @param filePath
	 * @return
	 * @Description <b>对输入流进行hash，以字符串形式返回40位的哈希值</b>
	 */
	public static String SHAFileByInputStream(InputStream inputStream) {
		FileInputStream fileInputStream = null;  
	    DigestInputStream digestInputStream = null;  
	    
	    try {
			MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
			/*使用DigestInputStream  */
	        digestInputStream = new DigestInputStream(inputStream,messageDigest);
	        
	        /*read的过程中进行SHA处理，直到读完文件  */
	        byte[] buffer =new byte[BUFFER_SIZE];  
	        while (digestInputStream.read(buffer) > 0);  
	        
	        /*转换并返回结果，也是字节数组，包含16个元素  */
	        byte[] resultByteArray = messageDigest.digest();  
	        /*字符数组转换成字符串返回 */
	        return byteArrayToHex(resultByteArray); 
	        
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				digestInputStream.close();
				fileInputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	 /**
	 * @author  luohuida
	 * @time    Mar 7, 2015
	 * @param byteArray
	 * @return
	 * @Description <b>把字节转换为十六进制</b>
	 */
	public static String byteArrayToHex(byte[] byteArray) {
		      /*首先初始化一个字符数组，用来存放每个16进制字符*/
		      char[] hexDigits = {'0','1','2','3','4','5','6','7','8','9', 'A','B','C','D','E','F' };

		      /*new一个字符数组，这个就是用来组成结果字符串的（解释一下：一个byte是八位二进制，也就是2位十六进制字符（2的8次方等于16的2次方））*/
		      char[] resultCharArray =new char[byteArray.length * 2];

		      /*遍历字节数组，通过位运算（位运算效率高），转换成字符放到字符数组中去*/
		      int index = 0;
		      for (byte b : byteArray) {
		         resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
		         resultCharArray[index++] = hexDigits[b & 0xf];
		      }
		      
		      /*字符数组组合成字符串返回*/
		      return new String(resultCharArray);

		}

}
